﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Gp.Scripts.Core;
using Gp.Scripts.Core.Unit;
using Gp.Scripts.Data;
using Gp.Scripts.Data.Equip;
using Gp.Scripts.Data.Skills;
using QFramework;

namespace Gp.Scripts.Equip {
    [Serializable]
    public class WeaponEntity : IBonusProvider, ILogicEntity
    {
        public ConfigWeapon Config { get; private set; }

        public UnitEquipCom ComEquip { get; private set; }


        // public WeaponTypeInfo Info;


        private HashSet<WeaponPhraseDecorator> _decorators;
        public IEnumerable<WeaponPhraseDecorator> Decorators => _decorators;


        public WeaponTypeCode TypeCode => WeaponTypeCode.None;


        // 当前耐久度
        public WeaponEntity(ConfigWeapon config, UnitEquipCom ComEquip) {
            Config = config;
            this.ComEquip = ComEquip;

            _decorators = new HashSet<WeaponPhraseDecorator>();
            _decorators.ForEach(d => d.Init(this));

 
            
            ComEquip.Unit.RegisterEvent<Event_Unit.BlockAttack>(AfterDefence);
        }


        public int GetDamage() {
            ModifierValue bonus = _decorators
                .Select(x => x.DamageBonus())
                .Aggregate(ModifierValue.Zero, (cur, v) => cur + v);

            // 武器类型伤害 
            return bonus.ResultInt(Config.Damage);
        }


        public int GetDamage(BaseUnit target) {
            ModifierValue bonus = _decorators
                .Select(x => x.DamageBonus(target))
                .Aggregate(ModifierValue.Zero, (cur, v) => cur + v);

            // 武器类型伤害 
            return bonus.ResultInt(Config.Damage);
        }
        


        public void AfterAttack(BaseUnit target, AttackActionResult res) {
            // Info.AfterAttack(target, res);
            foreach (var x in Decorators) {
                x.AfterAttack(target, res);
            }
        }


        public void AfterDefence(Event_Unit.BlockAttack args) {
            if (ComEquip.CurWeapon != this) return;

            // Info.AfterDefence(args.AttackPreReaction);
            foreach (var x in Decorators) {
                x.AfterBlock(args.AttackPreReaction);
            }
        }


        public IEnumerator SmallTurnStart(TurnState state) {
            // Info.SmallTurnStart(state);
            return Decorators.Select(d => d.SmallTurnStart(state)).GetEnumerator();
        }

        public void SmallTurnEnd(TurnState state) {
            // Info.SmallTurnEnd(state);
            Decorators.ForEach(d => d.SmallTurnEnd(state));
        }

        public IEnumerable<BonusNumber> Bonus() {
            // foreach (var b in Config.Bonus()) {
            //     yield return b;
            // }

            foreach (var b in _decorators.SelectMany(d => d.Bonus())) {
                yield return b;
            }
        }

        public ILogicEntity GetBonusProviderInfo() {
            return this;
        }

        public IEntityConfig GetConfig()
        {
            return Config;
        }


        public List<SkillTags> SkillTag() {
            var list = new List<SkillTags>(_decorators.SelectMany(d => d.Tags()));
            // list.AddRange(Info.SkillTag());
            return list;
        }

        public IReadOnlyList<WeaponTag> WeaponTags() {
            // return Config.weaponTagList;
            return new List<WeaponTag>();
        }

        public IEnumerable<WeaponAbilityEntity> WeaponAbilities() {
            // foreach (var entity in Info.WeaponAbilities()) {
            //     yield return entity;
            // }
            
            foreach (var entity in _decorators.SelectMany(x => x.WeaponAbility())) {
                yield return entity;
            }

            foreach (var entity in ComEquip.Unit.ComPro.GetWeaponAbilities(this)) {
                yield return entity;
            }
        }
    }
}